package com.kurt.controller;

import com.kurt.common.PageResult;
import com.kurt.common.Result;
import com.kurt.util.JwtUtil;
import com.kurt.util.UserContext;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 控制器基类
 * 提供通用的控制器功能，包括用户信息获取、token解析等
 *
 * @author Kurt
 */
@Slf4j
public class BaseController {

    @Autowired
    private JwtUtil jwtUtil;

    /**
     * 获取当前登录用户ID
     * 优先从UserContext获取，如果为空则从token解析
     */
    protected Long getCurrentUserId() {
        // 先从UserContext获取（由JwtInterceptor设置）
        Long userId = UserContext.getUserId();
        if (userId != null) {
            return userId;
        }

        // 如果UserContext中没有，则从token解析
        String token = getTokenFromRequest();
        if (token != null) {
            try {
                userId = jwtUtil.getUserIdFromToken(token);
                // 设置到UserContext中
                UserContext.setUserId(userId);
                return userId;
            } catch (Exception e) {
                log.error("从token解析用户ID失败", e);
            }
        }

        throw new RuntimeException("用户未登录");
    }

    /**
     * 获取当前登录用户名
     * 优先从UserContext获取，如果为空则从token解析
     */
    protected String getCurrentUsername() {
        // 先从UserContext获取（由JwtInterceptor设置）
        String username = UserContext.getUsername();
        if (username != null) {
            return username;
        }

        // 如果UserContext中没有，则从token解析
        String token = getTokenFromRequest();
        if (token != null) {
            try {
                username = jwtUtil.getUsernameFromToken(token);
                // 设置到UserContext中
                UserContext.setUsername(username);
                return username;
            } catch (Exception e) {
                log.error("从token解析用户名失败", e);
            }
        }

        throw new RuntimeException("用户未登录");
    }

    /**
     * 获取当前登录用户组织ID
     * 优先从UserContext获取，如果为空则从token解析
     */
    protected Long getCurrentOrganizationId() {
        // 先从UserContext获取（由JwtInterceptor设置）
        Long organizationId = UserContext.getOrganizationId();
        if (organizationId != null) {
            return organizationId;
        }

        // 如果UserContext中没有，则从token解析
        String token = getTokenFromRequest();
        if (token != null) {
            try {
                organizationId = jwtUtil.getOrganizationIdFromToken(token);
                // 设置到UserContext中
                UserContext.setOrganizationId(organizationId);
                return organizationId;
            } catch (Exception e) {
                log.error("从token解析组织ID失败", e);
            }
        }

        throw new RuntimeException("用户未配置组织");
    }

    /**
     * 检查用户是否已登录
     */
    protected boolean isUserLoggedIn() {
        // 先检查UserContext
        if (UserContext.hasUser()) {
            return true;
        }

        // 检查token
        String token = getTokenFromRequest();
        if (token != null) {
            try {
                return jwtUtil.validateToken(token);
            } catch (Exception e) {
                log.error("验证token失败", e);
            }
        }

        return false;
    }

    /**
     * 从请求中获取token
     * 支持从Authorization header和cookie中获取
     */
    protected String getTokenFromRequest() {
        HttpServletRequest request = getRequest();
        if (request == null) {
            return null;
        }

        // 优先从Authorization header获取
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }

        // 从cookie中获取
        jakarta.servlet.http.Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (jakarta.servlet.http.Cookie cookie : cookies) {
                if ("token".equals(cookie.getName())) {
                    return cookie.getValue();
                }
            }
        }

        // 从请求参数中获取
        String token = request.getParameter("token");
        if (token != null && !token.isEmpty()) {
            return token;
        }

        return null;
    }

    /**
     * 获取request
     */
    public HttpServletRequest getRequest() {
        return getRequestAttributes().getRequest();
    }

    /**
     * 获取response
     */
    public jakarta.servlet.http.HttpServletResponse getResponse() {
        return getRequestAttributes().getResponse();
    }

    /**
     * 获取RequestAttributes
     */
    public ServletRequestAttributes getRequestAttributes() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

    /**
     * 响应请求分页数据
     */
    protected <T> Result<PageResult<T>> getDataTable(org.springframework.data.domain.Page<T> page) {
        PageResult<T> pageResult = PageResult.of(
                page.getNumber() + 1,
                page.getSize(),
                page.getTotalElements(),
                page.getContent()
        );
        return Result.success("查询成功", pageResult);
    }

    /**
     * 响应返回结果
     *
     * @param rows 影响行数
     * @return 操作结果
     */
    protected Result<Boolean> toAjax(int rows) {
        return rows > 0 ? Result.success("操作成功", true) : Result.error("操作失败");
    }

    /**
     * 响应返回结果
     *
     * @param result 结果
     * @return 操作结果
     */
    protected Result<Boolean> toAjax(boolean result) {
        return result ? Result.success("操作成功", true) : Result.error("操作失败");
    }

    /**
     * 页面跳转
     */
    public String redirect(String url) {
        return String.format("redirect:%s", url);
    }

    /**
     * 参数校验
     */
    protected void validate(Object... params) {
        for (Object param : params) {
            if (param instanceof String && ((String) param).isEmpty()) {
                throw new RuntimeException("参数不能为空");
            }
            if (param == null) {
                throw new RuntimeException("参数不能为空");
            }
        }
    }

    /**
     * 获取当前登录用户的 IP 地址
     */
    protected String getClientIp() {
        HttpServletRequest request = getRequest();
        String ip = request.getHeader("X-Forwarded-For");
        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
            // 多个IP时，第一个为真实IP
            int index = ip.indexOf(',');
            if (index != -1) {
                ip = ip.substring(0, index);
            }
            return ip.trim();
        }

        ip = request.getHeader("Proxy-Client-IP");
        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
            return ip.trim();
        }

        ip = request.getHeader("WL-Proxy-Client-IP");
        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
            return ip.trim();
        }

        ip = request.getRemoteAddr();
        return ip;
    }

    /**
     * 反射获取属性值（支持getter和字段，未找到返回默认值）
     */
    protected Object getValue(Object o, String fieldName, Object defaultValue) {
        try {
            Method getter = o.getClass().getMethod("get" + upperFirst(fieldName));
            return getter.invoke(o);
        } catch (Exception ignore) {
            try {
                Field f = o.getClass().getDeclaredField(fieldName);
                f.setAccessible(true);
                return f.get(o);
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    /**
     * 首字母大写
     */
    private String upperFirst(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
} 